/**
 * 
 */
package co.fitstart.coach.web.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.support.Result;
import com.demo2do.core.web.handler.CookieHandler;
import com.demo2do.core.web.interceptor.WechatWebSniffer;
import com.demo2do.core.web.utils.WebUtils;
import com.demo2do.core.wechat.authorization.AuthorizationScope;
import com.demo2do.core.wechat.authorization.handler.AppAuthHandler;
import com.demo2do.core.wechat.authorization.handler.CorpAuthHandler;
import com.demo2do.core.wechat.support.AppType;

import co.fitstart.coach.web.interceptor.AutoLogin;

/**
 * @author lute
 *
 */
@Controller
@RequestMapping("")
public class AuthorizationController {

    private static final Logger logger = LoggerFactory.getLogger(AuthorizationController.class);
    
    private static final String SAVED_REQUEST = "WECHAT_WEB_SNIFFER_SAVED_REQUEST";
    
    @Value("#{weixin['userid.key']}")
    private String useridKey;
    
    @Autowired
    private AppAuthHandler appAuthHandler;
    
    @Autowired
    private CorpAuthHandler corpAuthHandler;
    
    @Autowired
    private CookieHandler cookieHandler;
    
    /**
     * Prepare WeChat authorization code URL and redirect to it
     * 
     * @param httpServletRequest
     * @return
     */
    @RequestMapping("/wx/pre-auth")
    @WechatWebSniffer(ignore = true)
    @AutoLogin(ignore = true)
    public String prepareWechatAuth(HttpServletRequest httpServletRequest) {
        String serverRealPath = WebUtils.getRealServerPath(httpServletRequest);
        String codeUrl = appAuthHandler.generateCodeUrl(serverRealPath + "/wx/post-auth", AuthorizationScope.BASE, AppType.CORPORATION, null);
        return "redirect:" + codeUrl;
    }
    
    /**
     * Receive code from WeChat and request userid
     * 
     * @param code
     * @param state
     * @param httpServletResponse
     * @param httpSession
     * @return
     */
    @RequestMapping("/wx/post-auth")
    @WechatWebSniffer(ignore = true)
    @AutoLogin(ignore = true)
    public ModelAndView onPostAuthorization(@RequestParam(value = "code", required = false) String code,
                                            @RequestParam(value = "state", required = false) String state,
                                            HttpServletResponse httpServletResponse,
                                            HttpSession httpSession) {
        
        ModelAndView modelAndView = new ModelAndView();
        
        // Get saved request url from http session
        String originalURL = (String) httpSession.getAttribute(SAVED_REQUEST);
        
        // If code returned from WeChat is not empty, then go to retrieve userid using code
        if (StringUtils.isNoneBlank(code)) {
            
            Result result = corpAuthHandler.requestUserInfo(code);
            
            if (result.isValid()) { 
                
                String userid = (String) result.get("UserId");
                
                logger.trace("WechatAuthorizationController#onPostAuthorization() - Get userid [" + userid + "].");
                
                // If userid retrieved successfully, add userid to cookie
                if (StringUtils.isNotBlank(userid)) {
                    
                    cookieHandler.addCookie(httpServletResponse, useridKey, userid);
                    
                    // If original url is not empty, redirect to original url. Or redirect to root path.
                    if (StringUtils.isNotBlank(originalURL)) {
                        modelAndView.setViewName("redirect:" + originalURL);
                    } else {
                        modelAndView.setViewName("redirect:/");
                    }
                } else {
                    // Handle unauthenticated situation...
                    modelAndView.setViewName("redirect:/403");
                }
                return modelAndView;
                
            } else {
                // Add error message to modelAndView
                modelAndView.addObject("errmsg", (String) result.get("errmsg"));
            }
            
        } else {
            logger.error("WechatAuthorizationController#onPostAuthoirzation() - Request WeChat code occurs unknown errors. No code returned from WeChat.");
        }
        
        // Display WeChat authorization error page
        modelAndView.setViewName("auth-error");
        return modelAndView;
        
    }

    
    /**
     * all the authorization problem will redirect to this method
     * 
     * @return
     */
    @RequestMapping(value = {"/auto-login-error", "/403"}, method = RequestMethod.GET)
    @WechatWebSniffer(ignore = true)
    @AutoLogin(ignore = true)
    public String authorizeError() {
        return "authorize-error";
    }
    
}
